using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using Xeml.Document.Contracts;
using Xeml.Sampling;
using System.Threading;
using Mpi.Common.Controls;

namespace Xid.Controls
{
    public partial class TableFormatterCtrl : UserControl, IBusyReporter
    {
        //BackgroundWorker _tableFormatterWorker;
        //private void InitWorker()
        //{
        //    _tableFormatterWorker = new BackgroundWorker();
        //    _tableFormatterWorker.WorkerReportsProgress = true;
        //    _tableFormatterWorker.DoWork += new DoWorkEventHandler(_tableFormatterWorker_DoWork);
        //    _tableFormatterWorker.ProgressChanged += new ProgressChangedEventHandler(_tableFormatterWorker_ProgressChanged);
        //}

        //void _tableFormatterWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        //{
        //    switch (e.ProgressPercentage)
        //    {
        //        case 0:
        //            {
        //                OnBackgroundWorkStarted("Formatting table.");
        //                break;
        //            }
        //        case 20:
        //            {
        //                PopulateSampleColumnEmitterTree(sce);
        //                PopulateParameterColumnEmitterTree(pce);
        //                PopulateEventColumnEmitterTree(ece);
        //                this.kryptonDataGridView1.DataSource = null;
        //                break;
        //            }
        //        case 50:
        //            {
        //                this.kryptonDataGridView1.DataSource = _table;
        //                foreach (DataGridViewColumn var in kryptonDataGridView1.Columns)
        //                {
        //                    DataTable dt = (DataTable)kryptonDataGridView1.DataSource;
        //                    var.HeaderText = dt.Columns[var.DataPropertyName].Caption;

        //                }
        //                break;
        //            }
        //        case 100:
        //            {
        //                OnBackgroundWorkEnded();
        //                break;
        //            }
        //        default:
        //            break;
        //    }
        //}

        //void _tableFormatterWorker_DoWork(object sender, DoWorkEventArgs e)
        //{
        //    BackgroundWorker bw = sender as BackgroundWorker;
        //    bw.ReportProgress(0);
        //    //Thread.Sleep(1000);
        //    Format();
        //    //bw.ReportProgress(50);
        //    //Thread.Sleep(1000);
        //    bw.ReportProgress(100);
        //}


        private IDocument _xemlDoc;

        public IDocument XemlDoc
        {
            get { return _xemlDoc; }
            //set
            //{

            //    _xemlDoc = value;
            //    if (_xemlDoc != null)
            //        _tableFormatterWorker.RunWorkerAsync();
            //}
        }

        public TableFormatterCtrl()
        {
            InitializeComponent();
            // InitWorker();

        }
        StandardTableFormatter stf = new StandardTableFormatter();
        ParameterColumnEmitter pce;
        PositionColumnEmitter poe;
        SampleColumnEmitter sce;
        EventColumnEmitter ece;
        //ObPointColumnEmitter oce;
        DataTable _table;
        public void Format(IDocument xemlDoc)
        {
            OnBackgroundWorkStarted("Formatting table.");
            try
            {

                _xemlDoc = xemlDoc;
                stf.Emitter.Clear();
                pce = new ParameterColumnEmitter();
                poe = new PositionColumnEmitter();
                sce = new SampleColumnEmitter();
                ece = new EventColumnEmitter();
                // oce = new ObPointColumnEmitter();
                sce.Emit(this.XemlDoc);
                pce.Emit(this.XemlDoc);
                ece.Emit(this.XemlDoc);
                poe.Emit(this.XemlDoc);
                // oce.Emit(this.XemlDoc);



                stf.Emitter.Add(sce);
                stf.Emitter.Add(pce);
                stf.Emitter.Add(poe);
                stf.Emitter.Add(ece);
                // stf.Emitter.Add(oce);

                //_tableFormatterWorker.ReportProgress(20);
                PopulateSampleColumnEmitterTree(sce,true);
                PopulateSampleColumnEmitterTree(poe, false);
                PopulateParameterColumnEmitterTree(pce);
                PopulateEventColumnEmitterTree(ece);
                //  PopulateObPointColumnEmitterTree(oce);
                this.kryptonDataGridView1.DataSource = null;



                _table = stf.Format(this.XemlDoc);

                BindToGrid(_table);
                kryptonDataGridView1.AutoResizeColumns();

            }
            finally
            {

                OnBackgroundWorkEnded();

            }

        }


        DataTable _lastTable;
        private void BindToGrid(DataTable dt)
        {
            kryptonDataGridView1.CellValueNeeded -= new DataGridViewCellValueEventHandler(kryptonDataGridView1_CellValueNeeded);
            _lastTable = dt;
            dt.DefaultView.Sort = "[SampleId] asc";



            kryptonDataGridView1.ColumnHeadersHeight = 80;


            DataGridViewColumn[] columns = new DataGridViewColumn[dt.Columns.Count];
            kryptonDataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
            for (int i = 0; i < columns.Length; ++i)
            {
                DataGridViewColumn column = new DataGridViewTextBoxColumn();
                column.Visible = (dt.Columns[i] as XemlDataColumn).Visible;
                column.Name = dt.Columns[i].ColumnName;
                column.HeaderCell.Style.WrapMode = DataGridViewTriState.True;
                column.DefaultCellStyle.WrapMode = DataGridViewTriState.False;
                column.FillWeight = 1;
                column.HeaderText = dt.Columns[i].Caption;
                column.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
                columns[i] = column;
            }
            kryptonDataGridView1.Columns.Clear();

            kryptonDataGridView1.RowCount = dt.Rows.Count;

            this.kryptonDataGridView1.Columns.AddRange(columns);
            kryptonDataGridView1.Columns.RemoveAt(0);


            kryptonDataGridView1.CellValueNeeded += new DataGridViewCellValueEventHandler(kryptonDataGridView1_CellValueNeeded);
        }

        //private void PopulateObPointColumnEmitterTree(ColumnEmitter ece)
        //{
        //    treeViewObPoints.AfterCheck -= new TreeViewEventHandler(OnNodeChecked);
        //    treeViewObPoints.Nodes.Clear();
        //    TreeNode root = treeViewObPoints.Nodes.Add(ece.Name);
        //    root.Checked = true;
        //    root.Tag = ece;

        //    foreach (Column c in ece.Columns.Values)
        //    {
        //        AddNodes(root, c);
        //    }
        //    root.Expand();
        //    treeViewObPoints.AfterCheck += new TreeViewEventHandler(OnNodeChecked);
        //}

        private void PopulateEventColumnEmitterTree(ColumnEmitter ece)
        {
            treeViewEvents.AfterCheck -= new TreeViewEventHandler(OnNodeChecked);
            treeViewEvents.Nodes.Clear();
            TreeNode root = treeViewEvents.Nodes.Add(ece.Name);
            root.Checked = true;
            root.Tag = ece;

            foreach (Column c in ece.Columns.Values)
            {
                AddNodes(root, c);
            }
            root.ExpandAll();
            treeViewEvents.AfterCheck += new TreeViewEventHandler(OnNodeChecked);
        }

        private void PopulateSampleColumnEmitterTree(ColumnEmitter sce, bool clear)
        {
            treeView1.AfterCheck -= new TreeViewEventHandler(OnNodeChecked);
            if (clear)
                treeView1.Nodes.Clear();
            TreeNode root = treeView1.Nodes.Add(sce.Name);
            root.Checked = true;
            root.Tag = sce;

            foreach (Column c in sce.Columns.Values)
            {
                AddNodes(root, c);
            }
            root.ExpandAll();
            treeView1.AfterCheck += new TreeViewEventHandler(OnNodeChecked);
        }

        private void PopulateParameterColumnEmitterTree(ParameterColumnEmitter pce)
        {
            treeView2.AfterCheck -= new TreeViewEventHandler(OnNodeChecked);
            treeView2.Nodes.Clear();
            TreeNode root = treeView2.Nodes.Add(pce.Name);
            root.Checked = true;
            root.Tag = pce;
            foreach (Column c in pce.Columns.Values)
            {
                AddNodes(root, c);
            }
            root.Expand();
            treeView2.AfterCheck += new TreeViewEventHandler(OnNodeChecked);

        }

        private static void AddNodes(TreeNode root, Column c)
        {
            TreeNode tn = new TreeNode();
            tn.Name = c.Name;
            tn.Text = c.NodeDisplayName;
            tn.Tag = c;
            tn.Checked = c.Enabled;
            root.Nodes.Add(tn);
            foreach (Column pc in c.SubColumns.Values)
            {
                AddNodes(tn, pc);
            }
        }



        private bool _suspended = false;
        private void OnNodeChecked(object sender, TreeViewEventArgs e)
        {
            OnBackgroundWorkStarted("Updating table.");
            try
            {
                TreeView tv = sender as TreeView;
                tv.AfterCheck -= new TreeViewEventHandler(OnNodeChecked);

                //if (e.Node.Tag is Column)
                //{
                //    (e.Node.Tag as Column).Enabled = e.Node.Checked;
                //    DownPopulateCheckState(e.Node, false);
                //}
                //else if (e.Node.Tag is ColumnEmitter)
                //{
                //    DownPopulateCheckState(e.Node, true);
                //}

                kryptonDataGridView1.SuspendLayout();
                DownPopulateCheckState(e.Node, true);
                kryptonDataGridView1.ResumeLayout();
                // this.kryptonDataGridView1.DataSource = 



                //BindToGrid(stf.Format(this.XemlDoc));
                //foreach (DataGridViewColumn var in kryptonDataGridView1.Columns)
                //{
                //    DataTable dt = (DataTable)kryptonDataGridView1.DataSource;
                //    var.HeaderText = dt.Columns[var.DataPropertyName].Caption;
                //}

                tv.AfterCheck += new TreeViewEventHandler(OnNodeChecked);
            }
            finally
            {
                OnBackgroundWorkEnded();
            }
        }

        private void DownPopulateCheckState(TreeNode t, bool recursiv)
        {
            if (t.Tag is Column)
            {
                (t.Tag as Column).Enabled = t.Checked;
                if (kryptonDataGridView1.Columns.Contains(t.Name) && kryptonDataGridView1.Columns[t.Name].Visible != t.Checked)
                    kryptonDataGridView1.Columns[t.Name].Visible = t.Checked;
            }
            foreach (TreeNode tn in t.Nodes)
            {
                tn.Checked = t.Checked;
                if (tn.Tag is Column)
                    (tn.Tag as Column).Enabled = tn.Checked;
                if (recursiv)
                    DownPopulateCheckState(tn, recursiv);
            }
        }

        public void CopyToClipBoard()
        {
            var x = this.kryptonDataGridView1.GetClipboardContent();
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < kryptonDataGridView1.Columns.Count; i++)
            {
                if (kryptonDataGridView1.Columns[i].Visible)
                    sb.AppendFormat("{0}\t", kryptonDataGridView1.Columns[i].HeaderText.Replace("\r\n", "_").Replace(" ", ""));
            }
            if (sb.Length > 0)
                sb.Remove(sb.Length - 1, 1);
            sb.Append("\r\n");

            for (int i = 0; i < kryptonDataGridView1.Rows.Count; i++)
            {
                for (int j = 0; j < kryptonDataGridView1.Columns.Count; j++)
                {
                    if (kryptonDataGridView1.Columns[j].Visible)
                        sb.AppendFormat("{0}\t", kryptonDataGridView1.Rows[i].Cells[j].Value.ToString().Replace("\r\n", ";"));
                }
                if (sb.Length > 0)
                    sb.Remove(sb.Length - 1, 1);
                sb.Append("\r\n");
            }


            if (sb.Length > 0)
                sb.Remove(sb.Length - 2, 2);

            Clipboard.SetText(sb.ToString());
            //Clipboard.SetDataObject(this.kryptonDataGridView1.GetClipboardContent(), true);
        }

        public event EventHandler<BusyEventArgs> BackgroundWorkStarted;
        public event EventHandler BackgroundWorkEnded;

        protected virtual void OnBackgroundWorkStarted(string message)
        {
            if (BackgroundWorkStarted != null)
                BackgroundWorkStarted(this, new BusyEventArgs(message));
        }

        protected virtual void OnBackgroundWorkEnded()
        {
            if (BackgroundWorkEnded != null)
                BackgroundWorkEnded(this, new EventArgs());
        }

        private void kryptonDataGridView1_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
        {
            e.Value = _lastTable.DefaultView[e.RowIndex].Row[e.ColumnIndex];
        }

        private void kryptonDataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            string sortasc = string.Format("[{0}] asc", kryptonDataGridView1.Columns[e.ColumnIndex].Name);
            string sortdesc = string.Format("[{0}] desc", kryptonDataGridView1.Columns[e.ColumnIndex].Name);

            if (_lastTable.DefaultView.Sort == sortasc)
                _lastTable.DefaultView.Sort = sortdesc;
            else
                _lastTable.DefaultView.Sort = sortasc;

            kryptonDataGridView1.Refresh();
        }


    }
}
